﻿using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net.WebSockets;
using System.Text;
using System.Threading.Channels;
using System.Threading.Tasks;

namespace FastIM
{
    /// <summary>
    /// 消息处理器
    /// </summary>
    public interface IMsgHandler
    {
        bool Accept(MsgTemplate msgTemplate);
        Task Handle(MsgTemplate msgTemplate, ImSession customWebSocket, ImServer server);
    }
    /// <summary>
    /// 消息处理管理器
    /// </summary>
    public class MsgHandlerManager
    {
        List<IMsgHandler> handlers = new List<IMsgHandler>();
        private static MsgHandlerManager _instance;
        /// <summary>
        /// 获取管理器实例
        /// </summary>
        /// <returns></returns>
        public static MsgHandlerManager Instance()
        {
            if (_instance == null) _instance = new MsgHandlerManager();
            return _instance;
        }
        public List<IMsgHandler> Add(IMsgHandler handler)
        {
            handlers.Add(handler);
            return handlers;
        }
        public List<IMsgHandler> Get()
        {
            return handlers;
        }
        public void Remove(IMsgHandler handler)
        {
            handlers.Remove(handler);
        }
        public void Clear() { handlers.Clear(); }
        public List<IMsgHandler> Init()
        {
            handlers.Add(new PingMsgHandler());
            handlers.Add(new OneMsgHandler());
            handlers.Add(new ChannelMsgHandler());
            handlers.Add(new AllMsgHandler());
            return handlers;
        }

    }

    /// <summary>
    /// 内置ping消息处理器实现，命令：ping
    /// </summary>
    public class PingMsgHandler : IMsgHandler
    {
        public bool Accept(MsgTemplate msgTemplate)
        {
            return msgTemplate != null && msgTemplate.Type == MsgType.PingReq;
        }

        public async Task Handle(MsgTemplate msgTemplate, ImSession customWebSocket, ImServer server)
        {
            //发送到其他客户端的数据
            var msgBody = new ResponseMsgBody { Code = 1 };//
            var sendMsg = Helper.SerializeObject(msgBody);
            byte[] sendByte = Encoding.UTF8.GetBytes(sendMsg);
            await customWebSocket.socket.SendAsync(new ArraySegment<byte>(sendByte, 0, sendByte.Length), WebSocketMessageType.Text, true, CancellationToken.None);
        }
    }
    /// <summary>
    /// 一对一单聊消息处理器，命令：onemsg
    /// </summary>
    public class OneMsgHandler : IMsgHandler
    {
        public bool Accept(MsgTemplate msgTemplate)
        {
            return msgTemplate != null && msgTemplate.Type == MsgType.PublishOne2One;
        }
        public async Task Handle(MsgTemplate msgTemplate, ImSession customWebSocket, ImServer server)
        {
            if (msgTemplate.Body == null) return;
            var body = (RequestMsgBody)msgTemplate.Body;
            await server.SendMessage(customWebSocket.clientId, body.ReceiveClientId, body.Payload, body.Qos, null, customWebSocket.clientMetaData,body.MsgId);
        }
    }
    /// <summary>
    /// 群聊频道聊消息处理器，命令：channelmsg
    /// </summary>
    public class ChannelMsgHandler : IMsgHandler
    {
        public bool Accept(MsgTemplate msgTemplate)
        {
            return msgTemplate != null && msgTemplate.Type == MsgType.Publish;
        }

        public async Task Handle(MsgTemplate msgTemplate, ImSession customWebSocket, ImServer server)
        {
            if (msgTemplate.Body == null) return;
            var body = (RequestMsgBody)msgTemplate.Body;
            await server.SendChanMessage(customWebSocket.clientId, body.Channel, body.Payload, customWebSocket.clientMetaData,body.MsgId);
        }
    }
    /// <summary>
    /// 全员消息处理器,命令：allmsg
    /// </summary>
    public class AllMsgHandler : IMsgHandler
    {
        public bool Accept(MsgTemplate msgTemplate)
        {
            return msgTemplate != null && msgTemplate.Type == MsgType.PublishOne2All;
        }

        public Task Handle(MsgTemplate msgTemplate, ImSession customWebSocket, ImServer server)
        {
            if (msgTemplate.Body == null) return Task.CompletedTask;
            var body = (RequestMsgBody)msgTemplate.Body;
            server.SendAllMessage(customWebSocket.clientId, body.Payload, customWebSocket.clientMetaData, body.MsgId);
            return Task.CompletedTask;
        }
    }
}
